#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
motifs_09 (motifs 09)
28 de diciembre de 2008
"""
#
import wx
import os
from numpy import array
from motifs_class_02 import MyMotifs
from motifs_graph_class_01 import GraphMotif
from motifs_xcel_class_02 import XcelMotif
from motifs_common_01 import AMINOACIDS, prob_aa, TEXTFROMFILE, TEXTDEFAULT
from motifs_graph_viewer_02 import Viewer
#
#
class MiMotivo(MyMotifs):
    def __init__(self, parent):
        MyMotifs.__init__(self, parent)
        self.graphout = "_graph.bmp"
        self.midict = dict()
        self.file = None
        self.anchor = None
        self.size = None
        self.prob_aa = None
        self.raw_frecs = None
        self.notes = None
        self.frecfile = False
        self.frectype = "Unknown"
        self.heading = []
        self.frecs = []
        self.graphs = []
        self.nonested = 0
        self.graphpath = None
        self.dict_prob_aa = prob_aa
        
        self.init()

    def init(self):
        ""
        try:
            for line in open("frecuencias.txt", 'r'):
                if line.strip() == "": continue
                if line.startswith("#"): continue
                [key, value] = line.split(':')
                key = key.strip()
                value = value.strip()
                if key == "name":
                    self.frectype = value
                    continue
                value = float(value)
                self.dict_prob_aa[key] = value
                self.frecfile = True
        except IOError:
            self.frecfile = False
    
        if self.frecfile:
            self.tc_out.WriteText(TEXTFROMFILE)
        else:
            self.frectype = "vertebrados"
            self.tc_out.WriteText(TEXTDEFAULT)

        self.heading.append("corregido para frecuencias de %s" %self.frectype)
        prob_list = [[self.dict_prob_aa[item]] for item in AMINOACIDS]
        self.prob_aa = array(prob_list)

    def fbbCallback(self, evt):
        self.file = evt.GetString()

    def doit(self, evt):
        ""
        self.heading = self.heading[0:1]
        if not self.file or not os.path.exists(self.file):
            graph = GraphMotif(AMINOACIDS)
            viewer = Viewer(graph.base, None, -1, "")
            viewer.Show()
            return
        #
        self.anchor = self.tc_anchor.GetValue()
        self.size = int(self.sp_size.GetValue())
        self.pattern = self.tc_pattern.GetValue()
        self.pos = int(self.sp_pos.GetValue())
        self.nonested = self.chbx_nonest.IsChecked()
        self.twoanchors = self.chbx_twoanc.IsChecked()
        #
        self.searchmotifs()
        if self.nonested:
            self.get_nonested()
            self.heading.append("Secuencias No Nested")
        if self.twoanchors:
            self.get_twoanchors()
            self.heading.append("Anchor 2 con %s en pos %s"
                                            %(self.pattern, self.pos))
        self.calc_frecs()
        #
        self.write_to_gui()
        self.graph_motifs()
        self.write_to_excel()
                            
    def write_to_gui(self):
        ""
        self.tc_out.Clear()
        self.write_motifs()
        self.write_frecs()
        self.write_notes()

    def get_nonested(self):
        ""
        total = []
        for item in self.midict:
            partial = []
            for sec in self.midict[item]:
                if sec in total:
                    continue
                else:
                    partial.append(sec)
                    total.append(sec)

            self.midict[item]= partial
    
    def get_twoanchors(self):
        ""
        print "in two anchors"
        for item in self.midict:
            partial = []
            for sec in self.midict[item]:
                if sec[self.pos-1] in self.pattern:
                    partial.append(sec)

            self.midict[item]= partial
    
    def get_percent_frecs(self, frecs):
        "porcentaje de las frecuencias"
        sumarray = frecs.sum(0)
        return frecs.astype(float)*100/sumarray

    def get_corrected_frecs(self, frecs):
        """
        dividir las frecuencias por la abundancia relativa y
        expresar en porcentage
        """
        corrected_frecs = frecs/self.prob_aa
        return self.get_percent_frecs(corrected_frecs)

    def searchmotifs(self):
        ""
        for item in open(self.file):
            #la file puede tener lineas comentadas
            if item.startswith("#"):continue
            item = item.strip()
            peptidos = []
            for ancla in self.anchor:
                index = -1
                while True:
                    index = item.find(ancla, index+1)
                    if index == -1: break
                    if len(item[index:]) >= self.size:
                        peptidos.append(item[index:index+self.size])
                    else:
                        break
            self.midict[item] = peptidos
    
    def calc_frecs(self):
        ""
        self.frecs = []
        self.notes = []
        aanumber = len(AMINOACIDS)
        lista = [0] * self.size * aanumber
        orden = dict()
        for item in AMINOACIDS:
            orden[item] = AMINOACIDS.index(item)
                
        self.raw_frecs = array(lista).reshape(aanumber, self.size)
            
        for item in self.midict:
            for motif in self.midict[item]:
                idx = 0
                for amino in motif:
                    try:
                        pos = orden[amino]
                    except KeyError:
                        self.notes.append("\namino %s desconocido. Asigno a 'X'"
                                          %amino)
                        pos = orden["X"]
                    
                    self.raw_frecs[pos][idx] += 1
                    idx += 1
        
        self.frecs.append((self.raw_frecs,
                            "frecuencias", self.heading[1:]))
        self.frecs.append((self.get_percent_frecs(self.raw_frecs),
                            "percent_frecs", self.heading[1:]))
        self.frecs.append((self.get_corrected_frecs(self.raw_frecs),
                            "correct_frecs", self.heading))
    
    def graph_motifs(self):
        ""
        self.graphs = []
        for frecuencias, name, heading in self.frecs:
            if name == "frecuencias": continue
            graph = GraphMotif(AMINOACIDS)
            graph.graph(frecuencias)
            filename = self.file.replace('.', '_')
            path = filename + '_' + name + self.graphout 
            graph.save(path)
            self.graphs.append((name, path, heading))
            viewer = Viewer(path, None, -1, name)
            viewer.Show()
    
    def write_to_excel(self):
        ""
        xmotif = XcelMotif()
        xmotif.sheet_motifs("motifs", self.midict)
        for frec, name, heading in self.frecs:
            xmotif.sheet_frecs(name, frec, heading)
        for name, path, heading in self.graphs:
            xmotif.sheet_graph(name+"_graph", path, heading)

        xmotif.xsave(self.file)
    
    def write_motifs(self):
        ""
        for item in self.midict:
            text = "%s\n%s\n\n" %(item, self.midict[item])
            self.tc_out.WriteText(text)
    
    def write_frecs(self):
        ""
        for frecs, name, heading in self.frecs:
            text = "\n%s\n" %name 
            for item in heading:
                text += "%s\n" %(item)  
            text += "pos -> "
            for number in range(self.size):
                text += "%6s  " %(number+1)
            self.tc_out.WriteText(text+'\n')
            
            for aa_idx, amino in enumerate(AMINOACIDS):
                text = " %s   -> " %amino
                for pos in range(self.size):
                    text += "%5.1f  " %(frecs[aa_idx][pos])
                self.tc_out.WriteText(text+'\n')
                
    def write_notes(self):
        ""
        if self.notes:
            notes = ''.join(self.notes)
            self.tc_out.WriteText(notes)
            
    def open(self, evt):
        if self.file:
            os.startfile(self.file + "out.xls")
            
          
if __name__ == '__main__':
    
    App=wx.PySimpleApp()
    fr = MiMotivo(None)
    fr.Show()
    App.MainLoop()